﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ID3_Algorithm.Tree;
using System.IO;

namespace ID3_Algorithm
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            SetUpAllVisibles();
        }

        private void SetUpAllVisibles()
        {
            txtBoxAtt1.Visible = false; 
            txtBoxAtt2.Visible = false;
            txtBoxAtt3.Visible = false;
            txtBoxAtt4.Visible = false;
            txtBoxAtt5.Visible = true;
            txtBoxAtt5.ReadOnly = true;

            checkBox1.Visible = true;
            checkBox2.Visible = false;
            checkBox2.Enabled = false;
            checkBox3.Visible = false;
            checkBox3.Enabled = false;
            checkBox4.Visible = false;
            checkBox4.Enabled = false;
            checkBox5.Visible = true;
            checkBox5.Enabled = true;
            checkBox5.Checked = true;

            //Att1 GRoupBox
            txtBoxValue11.Visible = false;
            txtBoxValue12.Visible = false;
            txtBoxValue13.Visible = false;
            txtBoxValue14.Visible = false;

            txtBoxValue21.Visible = false;
            txtBoxValue22.Visible = false;
            txtBoxValue23.Visible = false;
            txtBoxValue24.Visible = false;

            txtBoxValue31.Visible = false;
            txtBoxValue32.Visible = false;
            txtBoxValue33.Visible = false;
            txtBoxValue34.Visible = false;

            txtBoxValue41.Visible = false;
            txtBoxValue42.Visible = false;
            txtBoxValue43.Visible = false;
            txtBoxValue44.Visible = false;

            groupBoxAtt1.Hide();
            groupBoxAtt2.Hide();
            groupBoxAtt3.Hide();
            groupBoxAtt4.Hide();

            dataGridView1.Visible = false;
            tableLayoutPanel1.Visible = false;
            btnCalculateDecisonTree.Visible = false;
        }

        private DataTable MakeDataTable()
        {
            DataTable dt = new DataTable();

            //dt.Columns.Add(new DataColumn("Nr.", typeof(int)));

            if (txtBoxAtt1.Visible == true)
            {
                dt.Columns.Add(new DataColumn(txtBoxAtt1.Text, typeof(string)));
            }

            if (txtBoxAtt2.Visible == true)
            {
                dt.Columns.Add(new DataColumn(txtBoxAtt2.Text, typeof(string)));
            }

            if (txtBoxAtt3.Visible == true)
            {
                dt.Columns.Add(new DataColumn(txtBoxAtt3.Text, typeof(string)));
            }

            if (txtBoxAtt4.Visible == true)
            {
                dt.Columns.Add(new DataColumn(txtBoxAtt4.Text, typeof(string)));
            }

            dt.Columns.Add(new DataColumn(txtBoxAtt5.Text, typeof(string)));

            return dt;
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxAtt1.Visible = !txtBoxAtt1.Visible;

            if (checkBox1.Visible == true)
            {
                checkBox2.Visible = true;
            }
            if (checkBox1.Checked == true)
            {
                groupBoxAtt1.Show();
                checkBox2.Enabled = true;
            }
            else
            {
                groupBoxAtt1.Hide();
            }
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxAtt2.Visible = !txtBoxAtt2.Visible;
            if (checkBox2.Visible == true)
            {
                checkBox3.Visible = true;
            }

            if (checkBox2.Checked == true)
            {
                groupBoxAtt2.Show();
                checkBox3.Enabled = true;
            }
            else
            {
                groupBoxAtt2.Hide();
            }
        }

        private void checkBox3_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxAtt3.Visible = !txtBoxAtt3.Visible;
            if (checkBox3.Visible == true)
            {
                checkBox4.Visible = true;
            }

            if (checkBox3.Checked == true)
            {
                groupBoxAtt3.Show();
                checkBox4.Enabled = true;
            }
            else
            {
                groupBoxAtt3.Hide();
            }
        }

        private void checkBox4_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxAtt4.Visible = !txtBoxAtt4.Visible;
            //if (checkBox4.Visible == true)
            //{
            //    checkBox5.Visible = true;
            //}

            if (checkBox4.Checked == true)
            {
                groupBoxAtt4.Show();
                //checkBox5.Enabled = true;
            }
            else
            {
                groupBoxAtt4.Hide();
            }
        }

        private void checkBox5_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox5.Checked == false)
            {
                checkBox5.Checked = true;
            }
            
        }

        private void button1_Click(object sender, EventArgs e)
        {

            Dictionary<CheckBox, TextBox> attributeControls = new Dictionary<CheckBox, TextBox>();
            attributeControls.Add(checkBox1,txtBoxAtt1);
            attributeControls.Add(checkBox2,txtBoxAtt2);
            attributeControls.Add(checkBox3,txtBoxAtt3);
            attributeControls.Add(checkBox4,txtBoxAtt4);

            Dictionary<CheckBox, TextBox> att1Values = new Dictionary<CheckBox, TextBox>(); ;
            bool flagValues1Filled = false;
            if (checkBox1.Checked == true)
	        {
                att1Values.Add(checkBoxValue11, txtBoxValue11);
                att1Values.Add(checkBoxValue12, txtBoxValue12);
                att1Values.Add(checkBoxValue13, txtBoxValue13);
                att1Values.Add(checkBoxValue14, txtBoxValue14);
                flagValues1Filled = true;
	        }

            Dictionary<CheckBox, TextBox> att2Values = new Dictionary<CheckBox, TextBox>(); ;
            bool flagValues2Filled = false;
            if (checkBox2.Checked == true)
            {
                att2Values.Add(checkBoxValue21, txtBoxValue21);
                att2Values.Add(checkBoxValue22, txtBoxValue22);
                att2Values.Add(checkBoxValue23, txtBoxValue23);
                att2Values.Add(checkBoxValue24, txtBoxValue24);
                flagValues2Filled = true;
            }

            Dictionary<CheckBox, TextBox> att3Values = new Dictionary<CheckBox, TextBox>(); ;
            bool flagValues3Filled = false;
            if (checkBox3.Checked == true)
            {
                att3Values.Add(checkBoxValue31, txtBoxValue31);
                att3Values.Add(checkBoxValue32, txtBoxValue32);
                att3Values.Add(checkBoxValue33, txtBoxValue33);
                att3Values.Add(checkBoxValue34, txtBoxValue34);
                flagValues3Filled = true;
            }

            Dictionary<CheckBox, TextBox> att4Values = new Dictionary<CheckBox, TextBox>(); ;
            bool flagValues4Filled = false;
            if (checkBox4.Checked == true)
            {
                att4Values.Add(checkBoxValue41, txtBoxValue41);
                att4Values.Add(checkBoxValue42, txtBoxValue42);
                att4Values.Add(checkBoxValue43, txtBoxValue43);
                att4Values.Add(checkBoxValue44, txtBoxValue44);
                flagValues4Filled = true;
            }

            if (AtLeastTwoAttributesOK(attributeControls) == false || AtLeastTwoValuesOK(att1Values,flagValues1Filled) == false || AtLeastTwoValuesOK(att2Values,flagValues2Filled)==false || AtLeastTwoValuesOK(att3Values,flagValues3Filled)==false || AtLeastTwoValuesOK(att4Values,flagValues4Filled)==false)
            {
                MessageBox.Show("Please check your input","There are some errors");
            }
            else
            {
                LockAllAttributeControls();
                
                tableLayoutPanel1.Visible = true;
                dataGridView1.Visible = true;
                dataGridView1.DataSource = MakeDataTable();
                btnCalculateDecisonTree.Visible = true;
            }
        }

        private bool ValidateTextBoxInput(string msg)
        {
            if (msg.Equals(""))
            {
                return false;
            }
            else
                return true;
        }

        private void LockAllAttributeControls()
        {
            checkBox1.Enabled = false;
            checkBox2.Enabled = false;
            checkBox3.Enabled = false;
            checkBox4.Enabled = false;
            checkBox5.Enabled = false;

            txtBoxAtt1.ReadOnly = true;
            txtBoxAtt2.ReadOnly = true;
            txtBoxAtt3.ReadOnly = true;
            txtBoxAtt4.ReadOnly = true;
            txtBoxAtt5.ReadOnly = true;
        }

        private void checkBox6_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue11.Visible = !txtBoxValue11.Visible;
            if (checkBoxValue11.Visible == true)
            {
                checkBoxValue12.Visible = true;
            }
            if (checkBoxValue11.Checked == true)
            {
                txtBoxValue11.Visible = true;
            }
        }

        private void checkBoxValue12_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue12.Visible = !txtBoxValue12.Visible;
            if (checkBoxValue12.Visible == true)
            {
                checkBoxValue13.Visible = true;
            }
            if (checkBoxValue12.Checked == true)
            {
                txtBoxValue12.Visible = true;
            }
        }

        private void checkBoxValue13_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue13.Visible = !txtBoxValue13.Visible;
            if (checkBoxValue13.Visible == true)
            {
                checkBoxValue14.Visible = true;
            }
            if (checkBoxValue13.Checked == true)
            {
                txtBoxValue13.Visible = true;
            }
        }

        private void checkBoxValue14_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue14.Visible = !txtBoxValue14.Visible;
            //if (checkBoxValue14.Visible == true)
            //{
            //    checkBoxValue14.Visible = true;
            //}
            if (checkBoxValue14.Checked == true)
            {
                txtBoxValue14.Visible = true;
            }
        }

        private void checkBoxValue21_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue21.Visible = !txtBoxValue21.Visible;
            if (checkBoxValue21.Visible == true)
            {
                checkBoxValue22.Visible = true;
            }
            if (checkBoxValue21.Checked == true)
            {
                txtBoxValue21.Visible = true;

            }

        }

        private void button2_Click(object sender, EventArgs e)
        {   

            DataTable dt = (DataTable)dataGridView1.DataSource;
            List<Attribute> allAtt = FillAllAttributesFromForm();
            
            DecisionTree tree = new DecisionTree();
            tree.ConceptColumn = "C_x";
            tree.Root = tree.FormId3DecisionTree(dt,allAtt);

            string fileName = "DecisionTree.txt";
            PrintDecisionTreeToFile(tree.Root, fileName);

            MessageBox.Show("Decision tree is saved in file: "+ System.Environment.NewLine+System.Environment.CurrentDirectory+@"\"+fileName,"Calculation done.");
        }

        private List<Attribute> FillAllAttributesFromForm() 
        {
            List<Attribute> allAtt = new List<Attribute>();
            if (checkBox1.Checked == true)
            {
                List<string> allValuesForAtt1 = new List<string>();
                if (checkBoxValue11.Checked == true)
	            {
		            allValuesForAtt1.Add(txtBoxValue11.Text);
	            }
                if (checkBoxValue12.Checked == true)
	            {
		            allValuesForAtt1.Add(txtBoxValue12.Text);
	            }
                if (checkBoxValue13.Checked == true)
	            {
		            allValuesForAtt1.Add(txtBoxValue13.Text);
	            }
                if (checkBoxValue14.Checked == true)
	            {
		            allValuesForAtt1.Add(txtBoxValue14.Text);
	            }
                allAtt.Add(new Attribute(txtBoxAtt1.Text,allValuesForAtt1));
            }

            if (checkBox2.Checked == true)
            {
                List<string> allValuesForAtt2 = new List<string>();
                if (checkBoxValue21.Checked == true)
                {
                    allValuesForAtt2.Add(txtBoxValue21.Text);
                }
                if (checkBoxValue22.Checked == true)
                {
                    allValuesForAtt2.Add(txtBoxValue22.Text);
                }
                if (checkBoxValue23.Checked == true)
                {
                    allValuesForAtt2.Add(txtBoxValue23.Text);
                }
                if (checkBoxValue24.Checked == true)
                {
                    allValuesForAtt2.Add(txtBoxValue24.Text);
                }
                allAtt.Add(new Attribute(txtBoxAtt2.Text, allValuesForAtt2));
            }

            if (checkBox3.Checked == true)
            {
                List<string> allValuesForAtt3 = new List<string>();
                if (checkBoxValue31.Checked == true)
                {
                    allValuesForAtt3.Add(txtBoxValue31.Text);
                }
                if (checkBoxValue32.Checked == true)
                {
                    allValuesForAtt3.Add(txtBoxValue32.Text);
                }
                if (checkBoxValue33.Checked == true)
                {
                    allValuesForAtt3.Add(txtBoxValue33.Text);
                }
                if (checkBoxValue34.Checked == true)
                {
                    allValuesForAtt3.Add(txtBoxValue34.Text);
                }
                allAtt.Add(new Attribute(txtBoxAtt3.Text, allValuesForAtt3));
            }

            if (checkBox4.Checked == true)
            {
                List<string> allValuesForAtt4 = new List<string>();
                if (checkBoxValue41.Checked == true)
                {
                    allValuesForAtt4.Add(txtBoxValue41.Text);
                }
                if (checkBoxValue42.Checked == true)
                {
                    allValuesForAtt4.Add(txtBoxValue42.Text);
                }
                if (checkBoxValue43.Checked == true)
                {
                    allValuesForAtt4.Add(txtBoxValue43.Text);
                }
                if (checkBoxValue44.Checked == true)
                {
                    allValuesForAtt4.Add(txtBoxValue44.Text);
                }
                allAtt.Add(new Attribute(txtBoxAtt4.Text, allValuesForAtt4));
            }

            return allAtt;
        }

        private DataTable MakeAnotherTable(ref List<Attribute> allAtt)
        {
            DataTable dt = new DataTable();

            dt.Columns.Add("violence");
            dt.Columns.Add("nudity");
            dt.Columns.Add("horror");
            dt.Columns.Add("drugs");
            dt.Columns.Add("C_x");

            string[] row_1 = { "detailed", "none", "none", "yes","NO" };
            dt.Rows.Add(row_1);

            string[] row_2 = { "none", "none", "none", "no", "YES" };
            dt.Rows.Add(row_2);

            string[] row_3 = { "mild", "none", "occasional", "yes","NO" };
            dt.Rows.Add(row_3);

            string[] row_4 = { "mild", "mild", "sustained", "no","NO" };
            dt.Rows.Add(row_4);

            string[] row_5 = { "none", "none", "occasional", "no","YES" };
            dt.Rows.Add(row_5);

            string[] row_6 = { "detailed", "explicit", "none", "no","NO" };
            dt.Rows.Add(row_6);

            string[] row_7 = { "mild", "mild", "none", "no","YES" };
            dt.Rows.Add(row_7);

            string[] row_8 = { "none", "mild", "sustained", "no","NO" };
            dt.Rows.Add(row_8);

            Attribute attViolance = new Attribute("violence", new List<string>() { "detailed", "none","mild" });
            Attribute attNudity = new Attribute("nudity", new List<string>() { "none", "mild", "explicit" });
            Attribute attHorror = new Attribute("horror", new List<string>() { "none", "occasional", "sustained" });
            Attribute attDrugs = new Attribute("drugs", new List<string>() { "yes", "no" });

            allAtt = new List<Attribute> { attViolance,attNudity,attHorror,attDrugs };

            return dt;
        }

        private void checkBoxValue22_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue22.Visible = !txtBoxValue22.Visible;
            if (checkBoxValue22.Visible == true)
            {
                checkBoxValue23.Visible = true;
            }
            if (checkBoxValue22.Checked == true)
            {
                txtBoxValue22.Visible = true;
            }
        }

        private void checkBoxValue23_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue23.Visible = !txtBoxValue23.Visible;
            if (checkBoxValue23.Visible == true)
            {
                checkBoxValue24.Visible = true;
            }
            if (checkBoxValue23.Checked == true)
            {
                txtBoxValue23.Visible = true;
            }
        }

        private void checkBoxValue24_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue24.Visible = !txtBoxValue24.Visible;
            if (checkBoxValue24.Visible == true)
            {
                //checkBoxValue2.Visible = true;
            }
            if (checkBoxValue24.Checked == true)
            {
                txtBoxValue24.Visible = true;
            }
        }

        private void checkBoxValue31_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue31.Visible = !txtBoxValue31.Visible;
            if (checkBoxValue31.Visible == true)
            {
                checkBoxValue32.Visible = true;
            }
            if (checkBoxValue31.Checked == true)
            {
                txtBoxValue31.Visible = true;
            }
        }

        private void checkBoxValue32_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue32.Visible = !txtBoxValue32.Visible;
            if (checkBoxValue32.Visible == true)
            {
                checkBoxValue33.Visible = true;
            }
            if (checkBoxValue32.Checked == true)
            {
                txtBoxValue32.Visible = true;
            }
        }

        private void checkBoxValue33_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue33.Visible = !txtBoxValue33.Visible;
            if (checkBoxValue33.Visible == true)
            {
                checkBoxValue34.Visible = true;
            }
            if (checkBoxValue33.Checked == true)
            {
                txtBoxValue33.Visible = true;
            }
        }

        private void checkBoxValue34_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue34.Visible = !txtBoxValue34.Visible;
            if (checkBoxValue34.Visible == true)
            {
                //checkBoxValue35.Visible = true;
            }
            if (checkBoxValue34.Checked == true)
            {
                txtBoxValue34.Visible = true;
            }
        }

        private void checkBoxValue41_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue41.Visible = !txtBoxValue41.Visible;
            if (checkBoxValue41.Visible == true)
            {
                checkBoxValue42.Visible = true;
            }
            if (checkBoxValue41.Checked == true)
            {
                txtBoxValue41.Visible = true;
            }
        }

        private void checkBoxValue42_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue42.Visible = !txtBoxValue42.Visible;
            if (checkBoxValue42.Visible == true)
            {
                checkBoxValue43.Visible = true;
            }
            if (checkBoxValue42.Checked == true)
            {
                txtBoxValue42.Visible = true;
            }
        }

        private void checkBoxValue43_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue43.Visible = !txtBoxValue43.Visible;
            if (checkBoxValue43.Visible == true)
            {
                checkBoxValue44.Visible = true;
            }
            if (checkBoxValue43.Checked == true)
            {
                txtBoxValue43.Visible = true;
            }
        }

        private void checkBoxValue44_CheckedChanged(object sender, EventArgs e)
        {
            txtBoxValue44.Visible = !txtBoxValue44.Visible;
            if (checkBoxValue44.Visible == true)
            {
                //checkBoxValue45.Visible = true;
            }
            if (checkBoxValue44.Checked == true)
            {
                txtBoxValue44.Visible = true;
            }
        }

        private bool AtLeastTwoAttributesOK(Dictionary<CheckBox,TextBox> attControls) 
        {
            int totlalOKControls = 0;
            foreach (var item in attControls)
            {
                if (item.Key.Checked == true && item.Value.Text != "")
                {
                    totlalOKControls++;
                }
                if (item.Key.Checked == true && item.Value.Text == "" )
                {
                    return false;
                }
            }

            if (totlalOKControls > 1)
            {
                return true;
            }
            return false;
        }

        private bool AtLeastTwoValuesOK(Dictionary<CheckBox,TextBox> attValues, bool flag) 
        {
            if (flag == false)
            {
                return true;
            }
            else
            {
                int totlalOKValues = 0;
                foreach (var item in attValues)
                {
                    if (item.Key.Checked == true && item.Value.Text != "")
                    {
                        totlalOKValues++;
                    }
                }

                if (totlalOKValues > 1)
                {
                    return true;
                }
                return false;
            }
        }

        public void PrintDecisionTreeToFile(Tree.TreeNode root, String textFileName)
        {
            string stringToWrite = "Decision Tree" + System.Environment.NewLine;

            using (StreamWriter sw = new StreamWriter(textFileName))
            {
                stringToWrite = PrintTree(root, " ");
                sw.WriteLine(stringToWrite);
            }
        }

        private string PrintTree(Tree.TreeNode treeNode, string stringBuilder)
        {
            //string stringBuilder = " ";

            if (treeNode.Value.GetType() != typeof(string))
            {
                Attribute att = (Attribute)treeNode.Value;
                stringBuilder = System.Environment.NewLine + "Attribute: (" + att.Name + "), Values : ";

                for (int i = 0; i < treeNode.GetAllChildrenOfANode.Count; i++)
                {
                    stringBuilder += att.Values[i] + " =" + PrintTree(treeNode[i], stringBuilder) + "   ";
                }
            }
            else
            {
                stringBuilder = " <<" + (string)treeNode.Value + ">>   ";
            }
            return stringBuilder;
        }
        
    }
}
